package interaction.input.concrete;

import java.util.LinkedList;
import java.util.List;

import processing.core.PApplet;
import processing.core.PVector;
import interaction.ServiceLocator;
import interaction.game.GameObjectCollection;
import interaction.game.GameObjectFactory;
import interaction.game.Hero;
import interaction.sampling.Sample;
import interaction.sampling.SampleSet;
import interaction.sampling.matching.Matcher;

public class CalibrationGameComponent extends AbstractGameComponent<SampleSet>{
	private List<Sample> calibrationData;
	private Matcher sampleMatcher;
	private int consequentMatches = 0;
	private int consequentMatchesRequired;
	
	public CalibrationGameComponent(PVector position, PVector size, PApplet a, int consequentMatchesRequired) {
		super(position, size, a);
		this.consequentMatchesRequired = consequentMatchesRequired;
	}
	
	public void init()
	{
		super.init();
		Hero panda = getPanda();
		GameObjectCollection objects = getObjects();
		GameObjectFactory factory = getFactory();
		
	    objects.add(factory.createBackground());
	    objects.add(factory.createFoliage(panda));
	    objects.add(panda);
	    objects.add(factory.createEarth(panda));
	    
	    calibrationData = new LinkedList<Sample>();
	    sampleMatcher = ServiceLocator.getSampleMatcher();
	    consequentMatches = 0;
	}
	
	public SampleSet getSampleSet()
	{
		return new SampleSet(calibrationData);
	}
	
	public void beatReceived(Sample beat) {
		calibrationData.add(beat);
		SampleSet signature = getSampleSet();
		double rating = sampleMatcher.match(beat, signature);
		if (rating > sampleMatcher.getAcceptanceTreshold()) {
			beatMatched(beat);
			consequentMatches++;
			if (consequentMatches >= consequentMatchesRequired) {
				getDataSource().set(signature);
			}
		} else {
			consequentMatches = 0;
		}
	}
	
	public void beatMatched(Sample beat)
	{
	}

	public static class TapCalibration extends CalibrationGameComponent
	{

		public TapCalibration(PVector position, PVector size, PApplet a) {
			super(position, size, a, 10);
		}
		
		public void beatMatched(Sample beat) {
			getPanda().run();
		}
	}

	public static class SlapCalibration extends CalibrationGameComponent
	{

		public SlapCalibration(PVector position, PVector size, PApplet a) {
			super(position, size, a, 5);
		}
		
		public void beatMatched(Sample beat) {
			getPanda().jump();
		}
	}
}
